package com.pointcircle.estate.server.framework.web.api;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.fasterxml.jackson.annotation.JsonProperty;
import com.pointcircle.core.IRepository;
import com.pointcircle.core.entity.User;
import com.pointcircle.core.repository.UserRepository;
import com.pointcircle.core.web.EntityVo;
import com.pointcircle.core.web.IFindAllRest;
import com.pointcircle.core.web.IFindByIdRest;
import com.pointcircle.core.web.RestResponseElement;
import com.pointcircle.core.web.RestResponseList;
import com.pointcircle.estate.server.framework.entity.Building;
import com.pointcircle.estate.server.framework.entity.Ids;
import com.pointcircle.estate.server.framework.entity.Project;
import com.pointcircle.estate.server.framework.entity.QualityMeasureCheckQualityProblem;
import com.pointcircle.estate.server.framework.entity.QualityMeasureCheckQualityRepair;
import com.pointcircle.estate.server.framework.repository.BuildingRepository;
import com.pointcircle.estate.server.framework.repository.ProjectRepository;
import com.pointcircle.estate.server.framework.repository.QualityMeasureCheckQualityCcRepository;
import com.pointcircle.estate.server.framework.repository.QualityMeasureCheckQualityProblemRepository;
import com.pointcircle.estate.server.framework.repository.QualityMeasureCheckQualityRepairRepository;
import com.pointcircle.estate.server.framework.web.api.QualityMeasureCheckQualityProblemApi.QualityMeasureCheckQualityProblemEntityVo;

@RestController
@RequestMapping("/api/qualityMeasureCheckQualityRepair")
public class QualityMeasureCheckQualityRepairApi implements 
	IFindByIdRest<QualityMeasureCheckQualityRepair, String, QualityMeasureCheckQualityRepairApi.QualityMeasureCheckQualityRepairEntityVo>,
	IFindAllRest<QualityMeasureCheckQualityRepair, String, QualityMeasureCheckQualityRepairApi.QualityMeasureCheckQualityRepairEntityVo> {

	@Autowired
	private QualityMeasureCheckQualityRepairRepository repository;
	
	@Autowired
	private QualityMeasureCheckQualityProblemRepository problemRepository;
	
	@Autowired
	private ProjectRepository projectRepository;
	
	@Autowired
	private BuildingRepository buildingRepository;
	
	@Autowired
	private UserRepository userRepository;
	
	@Autowired
	private QualityMeasureCheckQualityProblemApi v3QualityMeasureCheckQualityProblemApi;
	
	@Autowired
	private QualityMeasureCheckQualityCcRepository qualityMeasureCheckQualityCcRepository;
	
	public class QualityMeasureCheckQualityRepairEntityVo extends EntityVo<QualityMeasureCheckQualityRepair, String> {
		public QualityMeasureCheckQualityRepairEntityVo(QualityMeasureCheckQualityRepair entity) {
			super(entity);
		}
		@JsonProperty("qualityMeasureCheckqualityProblemId")
		public String getQualityMeasureCheckqualityProblemId() {
			return entity.getQualityMeasureCheckqualityProblemId();
		}
		@JsonProperty("repair")
		public String getRepair() {
			return entity.getRepairId();
		}
		@JsonProperty("hasRead")
		public boolean hasRead() {
			return entity.getHasRead() != null ? entity.getHasRead() : false;
		}

		/*
		 * @JsonProperty("readingTimestamp") public Long readingTimestamp() { return
		 * entity.getReadingTime() != null ? entity.getReadingTime().getTime() : null; }
		 */
		@JsonProperty("readingTime")
		public Long readingTime() {
			return entity.getReadingTime() != null ? entity.getReadingTime().getTime() : null;
		}
		@JsonProperty("parentQualityMeasureCheckqualityRepairId")
		public String parentQualityMeasureCheckqualityRepairId() {
			return entity.getParentQualityMeasureCheckQualityRepairId();
		}
		@JsonProperty("childQualityMeasureCheckqualityRepairId")
		public String childQualityMeasureCheckqualityRepairId() {
			return entity.getChildQualityMeasureCheckQualityRepairId();
		}
	}

	@Override
	public IRepository<QualityMeasureCheckQualityRepair, String> getRepository() {
		return repository;
	}
	
	@GetMapping("findByProjectId")
	public RestResponseList findByBuildingId(
		@RequestParam("projectId") String projectId) {
		Project project = projectRepository.findOne(projectId);
		List<Building> buildings = buildingRepository.findByProject(project);
		List<QualityMeasureCheckQualityRepair> repairs = new LinkedList<QualityMeasureCheckQualityRepair>();
		buildings.forEach((building) -> {
			repairs.addAll(repository.findByBuilding(building));
		});
		return this.createRestResponseList(repairs);
	}
	
	@GetMapping("findByProblemIds")
	public RestResponseList findByProblemIds(@RequestParam("problemIds") List<String> problemIds){
		//List<String> problemIds = ids.getProblemIds();
		if(problemIds.size() < 1) {
			return this.createRestResponseList(new LinkedList<QualityMeasureCheckQualityRepair>());
		}
		List<QualityMeasureCheckQualityProblem> problems = problemRepository.findProblemsByProblemIds(problemIds);
		List<QualityMeasureCheckQualityRepair> qualityMeasureCheckQualityRepairs = problems.size() > 0 ? 
			repository.findByQualityMeasureCheckQualityProblemIn(problems) : 
			new LinkedList<QualityMeasureCheckQualityRepair>();
		return this.createRestResponseList(qualityMeasureCheckQualityRepairs);
	}
	
	@GetMapping("findByQualityMeasureProblemId")
	public RestResponseList findByQualityMeasureProblemId(
		@RequestParam("qualityMeasureProblemId") String qualityMeasureProblemId) {
		QualityMeasureCheckQualityProblem problem = problemRepository.findOne(qualityMeasureProblemId);
		List<QualityMeasureCheckQualityRepair> repairs = 
			repository.findByQualityMeasureCheckQualityProblem(problem);
		return this.createRestResponseList(repairs);
	}
	
	@GetMapping("changeRepair")
	public RestResponseElement changeRepair(
			@RequestParam(value = "qualityMeasureCheckqualityProblemId") String qualityMeasureCheckqualityProblemId,
			@RequestParam(value = "newRepairId") String newRepairId) {
		QualityMeasureCheckQualityProblem problem = problemRepository.findOne(qualityMeasureCheckqualityProblemId);
		User newRepair = userRepository.findOne(newRepairId);
		List<QualityMeasureCheckQualityRepair> repairList = repository.findByQualityMeasureCheckQualityProblem(problem);
		boolean isHaveRepair = false;
		QualityMeasureCheckQualityRepair tailRepair = null;
		for(QualityMeasureCheckQualityRepair repair : repairList) {
			if(repair.getRepair() == newRepair) {
				isHaveRepair = true;
			}
			if(repair.getChildQualityMeasureCheckQualityRepair() == null) {
				tailRepair = repair;
			}
		}
		RestResponseElement response = new RestResponseElement();
		if(!isHaveRepair) {
			QualityMeasureCheckQualityRepair newCheckQualityRepair = new QualityMeasureCheckQualityRepair();
			newCheckQualityRepair.setQualityMeasureCheckQualityProblem(problem);;
			newCheckQualityRepair.setParentQualityMeasureCheckQualityRepair(tailRepair);;
			newCheckQualityRepair.setRepair(newRepair);
			this.getRepository().saveAndFlush(newCheckQualityRepair);
			tailRepair.setChildQualityMeasureCheckQualityRepair(newCheckQualityRepair);
			this.getRepository().saveAndFlush(tailRepair);
			problem.setUpdateTime(new Date());
			problemRepository.saveAndFlush(problem);
			response.setSuccess(true);
			Map<String, Object> map = new HashMap<String, Object>();
			QualityMeasureCheckQualityProblemEntityVo problemVo = v3QualityMeasureCheckQualityProblemApi.generateEntityVo(problem);
			problemVo.setCcIds(qualityMeasureCheckQualityCcRepository.findCcIdsByQualityMeasureCheckQualityProblemId(problem.getId()));
			List<QualityMeasureCheckQualityRepair> repairs = repository.findByQualityMeasureCheckQualityProblem(problem);
			List<QualityMeasureCheckQualityRepairEntityVo> repairVoList = new ArrayList<>();
			for(QualityMeasureCheckQualityRepair repair : repairs) {
				repairVoList.add(new QualityMeasureCheckQualityRepairEntityVo(repair));
			}
			map.put("repairList", repairVoList);
			map.put("problem", problemVo);
			response.setElement(map);
		}else {
			response.setSuccess(false);
		}
		return response;
	}
}
